/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package za.co.pas.spaceandtime.data;

import javax.persistence.ManyToOne;
import za.co.pas.business.data.GenericData;
import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.OneToMany;

/**
 * Actual max capacity is stored in the room. Max cap from room type or beds are
 * only for user to double check
 * @author alabuschagne
 */
@Entity
public class Room extends GenericData implements Serializable
{

    private static final long serialVersionUID = 1L;
    private List<Bed> beds = new LinkedList<Bed>();
    private RoomType roomType;
    private Boolean shareBeds = Boolean.FALSE; //this is for a hostal - true
    private Boolean enabled = Boolean.FALSE;
    private Integer maxCapacity;
    private List<RoomCost> cost = new LinkedList<RoomCost>();
    private List<RoomExtra> extras =  new LinkedList<RoomExtra>();

    @Override
    public int hashCode()
    {
        return super.hashCode();
    }

    @Override
    public boolean equals(Object object)
    {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Room))
        {
            return false;
        }
        Room other = (Room) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id)))
        {
            return false;
        }
        return true;
    }

    /**
     * @return the beds
     */
    @OneToMany(cascade = CascadeType.ALL)
    public List<Bed> getBeds()
    {
        return beds;
    }

    /**
     * @param beds the beds to set
     */
    public void setBeds(List<Bed> beds)
    {
        this.beds = beds;
    }

    /**
     * @return the shareBeds
     */
    public Boolean getShareBeds()
    {
        return shareBeds;
    }

    /**
     * @param shareBeds the shareBeds to set
     */
    public void setShareBeds(Boolean shareBeds)
    {
        this.shareBeds = shareBeds;
    }

    public boolean check(Room otherRoom)
    {
        if (!super.check(otherRoom))
        {
            return false;
        }
        else if (shareBeds.compareTo(otherRoom.getShareBeds()) != 0)
        {
            return false;
        }
        else if ((roomType == null) && (otherRoom.getRoomType() != null))
        {
            return false;
        }
        else if ((roomType != null) && (roomType.check(otherRoom.getRoomType())))
        {
            return false;
        }
        else if ((beds == null) && (otherRoom.getBeds() != null))
        {
            return false;
        }
        else if (beds != null)
        {
            if (otherRoom.getBeds() == null)
            {
                return false;
            }
            if (beds.size() != otherRoom.getBeds().size())
            {
                return false;
            }
            ListIterator<Bed> itMe = beds.listIterator();
            while (itMe.hasNext())
            {
                boolean found = false;
                Bed bMe = itMe.next();
                ListIterator<Bed> itOther = otherRoom.getBeds().listIterator();
                while (itOther.hasNext())
                {
                    if (bMe.check(itOther.next()))
                    {
                        found = true;
                        break;//out of inner loop
                    }
                }
                if (!found)
                {
                    return false;
                }
            }
        }
        return true;
    }

    @Override
    public Room clone()
    {
        Room newRoom = new Room();
        newRoom.setDescription(description);
        newRoom.setId(id);
        newRoom.setName(name);
        newRoom.setShareBeds(shareBeds);
        newRoom.setRoomType(roomType);
        if(beds != null)
        {
            List<Bed> b = new LinkedList<Bed>();
            ListIterator<Bed> it = beds.listIterator();
            while(it.hasNext())
            {
                b.add(it.next().clone());
            }
            newRoom.setBeds(b);
        }
        return newRoom;
    }

    /**
     * @return the roomType
     */
    @ManyToOne(cascade = CascadeType.ALL)
    public RoomType getRoomType()
    {
        return roomType;
    }

    /**
     * @param roomType the roomType to set
     */
    public void setRoomType(RoomType roomType)
    {
        this.roomType = roomType;
    }

    /**
     * @return the enabled
     */
    public Boolean getEnabled()
    {
        return enabled;
    }

    /**
     * @param enabled the enabled to set
     */
    public void setEnabled(Boolean enabled)
    {
        this.enabled = enabled;
    }

    /**
     * @return the maxCapacity
     */
    public Integer getMaxCapacity()
    {
        return maxCapacity;
    }

    /**
     * @param maxCapacity the maxCapacity to set
     */
    public void setMaxCapacity(Integer maxCapacity)
    {
        this.maxCapacity = maxCapacity;
    }

    public void add(Bed bed)
    {
        if(beds == null)
        {
            beds = new LinkedList<Bed>();
        }
        beds.add(bed);
    }

    /**
     * @return the cost
     */
    @OneToMany
    public List<RoomCost> getCost()
    {
        return cost;
    }

    /**
     * @param cost the cost to set
     */
    public void setCost(List<RoomCost> cost)
    {
        this.cost = cost;
    }

    /**
     * @return the extras
     */
    @OneToMany
    public List<RoomExtra> getExtras()
    {
        return extras;
    }

    /**
     * @param extras the extras to set
     */
    public void setExtras(List<RoomExtra> extras)
    {
        this.extras = extras;
    }

    

   
}
